﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;

namespace BaseHelper.Net
{
    public class PortProtect
    {
        public delegate void AttackAlertHandler(string LocalIP,string RemoteIP,int Port);
        public static event AttackAlertHandler AttackAlertEvent;

        private static SortedList<int, Thread> _slThread = new SortedList<int, Thread>();
        private static string _alertMsg;

        public static bool Start(string AlertMsg, string Ports)
        {
            if (Ports.Length == 0)
                return false;

            List<int> lt = new List<int>();
            string[] ports = Ports.Contains(",") ? Ports.Split(',') : new string[] { Ports };

            foreach (string p in ports)
            {
                lt.Add(Convert.ToInt32(p));
            }
            return Start(AlertMsg, lt.ToArray());
        }
        public static bool Start(string AlertMsg,int[] Ports)
        {
            _alertMsg = AlertMsg;

            foreach (int port in Ports)
            {
                _slThread[port]= new Thread(new ParameterizedThreadStart(Listener));
                _slThread[port].Start(port);
            }
            return true;
        }


        public static void Stop()
        {
            try
            {
                foreach (Thread th in _slThread.Values)
                {
                    try
                    {
                        th.Abort();
                    }
                    catch { }
                }

                _slThread.Clear();
            }
            catch { }
        
        }

        public static void Listener(object obj)
        {
            int port = (int)obj;

            TcpListener tcpListener;
            byte[] alertMsg;


            try
            {
                tcpListener = new TcpListener(IPAddress.Any, port);
                tcpListener.Start();

                while (true)
                {
                    try
                    {
                        TcpClient client = tcpListener.AcceptTcpClient();
                        string remoteIP = client.Client.RemoteEndPoint.ToString().Split(':')[0];
                        string localIP = client.Client.LocalEndPoint.ToString().Split(':')[0];

                        if (AttackAlertEvent != null)
                            AttackAlertEvent(localIP,remoteIP, port);

                        alertMsg = Encoding.Default.GetBytes(_alertMsg.Replace("{ip}",remoteIP).Replace("{time}",DateTime.Now.ToString()));

                        NetworkStream ns = client.GetStream();
                        ns.Write(alertMsg, 0, alertMsg.Length);
                        ns.Flush();
                        client.Close();
                        
                    }
                    catch (Exception ex2)
                    {
                        Console.WriteLine("BaseHelper.Protect.PortProtect.cs -> Listener() " + ex2.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("BaseHelper.Protect.PortProtect.cs -> Listener() " + ex.Message);
            }
            
        
        }

    }
}
